package com.lshl.lingshang.http.manager;

import android.content.Context;
import android.util.LruCache;


import com.lshl.lingshang.application.MyApplication;
import com.lshl.lingshang.http.WAPI;
import com.lshl.lingshang.pub.GlobeConfig;
import com.lshl.lingshang.utils.LogUtil;

import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Description：请求管理类
 * Created on 2018/6/28 0028
 * Author : 郭
 */
public class RetrofitManager {
    public static final String TAG = RetrofitManager.class.getSimpleName();
    private static Retrofit mRetrofit;
    private static Context sContext;
    //默认超时时长
    private static final int DEFAULT_TIMEOUT = 30;
    //允许自己设置超时时长  默认必须为0
    private static int SETTING_TIMEOUT = 0;
    private ApiManager apiManager;
    private static LruCache<String, Context> mLruCache = new LruCache<>(5);

    private static class SingletonHolder {
        private static RetrofitManager INSTANCE = new RetrofitManager();
    }

    public static RetrofitManager getInstance() {
        if (sContext == null) {
            sContext = MyApplication.getInstance().getApplicationContext();
        }
//        mLruCache.put("")
        return SingletonHolder.INSTANCE;
    }

    private RetrofitManager() {
        // Log信息拦截器
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                //打印retrofit日志
                LogUtil.showAll("message --->" + message);
            }
        });
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        //设置 Debug Log 模式
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                // 设置超时
                .connectTimeout(SETTING_TIMEOUT==0?DEFAULT_TIMEOUT:SETTING_TIMEOUT, TimeUnit.SECONDS)
                .readTimeout(SETTING_TIMEOUT==0?DEFAULT_TIMEOUT:SETTING_TIMEOUT, TimeUnit.SECONDS)
                .writeTimeout(SETTING_TIMEOUT==0?DEFAULT_TIMEOUT:SETTING_TIMEOUT, TimeUnit.SECONDS)
                .retryOnConnectionFailure(true)
                .addInterceptor(loggingInterceptor)
                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Request.Builder requestBuilder = chain.request().newBuilder();
                        //避免空指针异常
//                        UserBean userInfo = GlobeConfig.getUserInfo();
//                        if (userInfo != null) {
//                            requestBuilder.addHeader(PubConst.REQUEST_TOKEN, StringUtil.StrTrim(userInfo.getAuthenticationToken()));
//                            requestBuilder.addHeader(PubConst.ID, StringUtil.StrTrim(userInfo.getId()));
//                        }
//                        requestBuilder.addHeader(PubConst.DEVICE_TOKEN,GlobeConfig.getUUID(sContext));
//                        requestBuilder.addHeader(PubConst.VERSION_CODE, StringUtil.StrTrim(AppUtil.getVersionCode(sContext)));
//                        requestBuilder.addHeader(PubConst.VERSION_NAME, StringUtil.StrTrim(AppUtil.getVersionName(sContext)));
                         Request build = requestBuilder.build();
                        return chain.proceed(build);
                    }
                });
        OkHttpClient okHttpClient = builder.build();
        mRetrofit = new Retrofit.Builder()
                .baseUrl(GlobeConfig.RELEASE?WAPI.ONLINE_URL: WAPI.TEST_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(okHttpClient)
                .build();
    }

    /**
     * create BaseApi  defalte ApiManager
     *
     * @return ApiManager
     */
    public ApiManager createApiManager() {

        return apiManager = create(ApiManager.class);
    }

    /**
     * create BaseApi  defalte ApiManager
     * 允许自己设置时长
     * @return ApiManager
     */
    public ApiManager createApiManagerWithTime(int timeout) {
        SETTING_TIMEOUT = timeout;
        return apiManager = create(ApiManager.class);
    }
    /**
     * create you ApiService
     * Create an implementation of the API endpoints defined by the {@code service} interface.
     */
    private <T> T create(final Class<T> service) {
        if (service == null) {
            throw new RuntimeException("Api service is null!");
        }
        return mRetrofit.create(service);
    }

    private static SSLSocketFactory getSSLSocketFactory(InputStream... certificates) {
        CertificateFactory certificateFactory = null;
        SSLContext sslContext = null;
        try {
            certificateFactory = CertificateFactory.getInstance("X.509");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);
            int index = 0;
            for (InputStream certificate : certificates) {
                String certificateAlias = Integer.toString(index++);
                keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
                try {
                    if (certificate != null)
                        certificate.close();
                } catch (IOException e) {
                }
            }
            sslContext = SSLContext.getInstance("TLS");
            TrustManagerFactory trustManagerFactory =
                    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            sslContext.init
                    (null, trustManagerFactory.getTrustManagers(), new SecureRandom());
        } catch (CertificateException pE) {
            pE.printStackTrace();
        } catch (NoSuchAlgorithmException pE) {
            pE.printStackTrace();
        } catch (KeyStoreException pE) {
            pE.printStackTrace();
        } catch (KeyManagementException pE) {
            pE.printStackTrace();
        } catch (IOException pE) {
            pE.printStackTrace();
        }
        return sslContext.getSocketFactory();
    }
}
